using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UIElements;

namespace CodeMonkey.Toolkit {

    [InitializeOnLoad]
    public class MainWindowToolkit : EditorWindow {


        [SerializeField] private CodeMonkeyToolkitSO codeMonkeyToolkitSO;
        [SerializeField] private VisualTreeAsset visualTreeAsset;
        [SerializeField] private VisualTreeAsset textTemplateVisualTreeAsset;
        [SerializeField] private VisualTreeAsset codeTemplateVisualTreeAsset;
        [SerializeField] private VisualTreeAsset videoTemplateVisualTreeAsset;
        [SerializeField] private VisualTreeAsset toolListEntryVisualTreeAsset;
        [SerializeField] private VisualTreeAsset toolTagSingleVisualTreeAsset;


        static MainWindowToolkit() {
            EditorApplication.update += Startup;
        }

        private static void Startup() {
            EditorApplication.update -= Startup;

            try {
                CodeMonkeyToolkitSO codeMonkeyInteractiveSO = CodeMonkeyToolkitSO.GetCodeMonkeyToolkitSO();
                long unixTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
                long secondsBetweenShowingWindow = 60 * 60 * 24;
                if (unixTimestamp - codeMonkeyInteractiveSO.lastShownTimestamp < secondsBetweenShowingWindow) {
                    // Too soon
                    return;
                }
                
                codeMonkeyInteractiveSO.lastShownTimestamp = unixTimestamp;

                // ERROR: Auto-show window disabled because it breaks Multiplayer Play Mode?
                //ShowWindow();
            } catch (Exception e) {
                Debug.LogError(e);
            }
        }



        private enum SubWindow {
            MainMenu,
            ToolList,
            ToolSingle,
        }


        private VisualElement toolListVisualElement;
        private VisualElement toolSingleVisualElement;
        private VisualElement mainMenuVisualElement;
        private ToolSO toolSO;
        private Vector2 lastListScrollPosition;
        private SubWindow lastSubWindow;


        [MenuItem("Tools/Code Monkey Toolkit", priority = 0)]
        public static void ShowWindow() {
            try {
                MainWindowToolkit window = GetWindow<MainWindowToolkit>();
                window.titleContent = new GUIContent("Code Monkey Toolkit");
            } catch (Exception e) {
                Debug.LogError(e);
            }
        }

        public static void DestroyChildren(VisualElement containerVisualElement) {
            foreach (VisualElement child in containerVisualElement.Children().ToList()) {
                containerVisualElement.Remove(child);
            }
        }

        public static void AddComplexText(
            VisualTreeAsset textTemplateVisualTreeAsset,
            VisualTreeAsset codeTemplateVisualTreeAsset,
            VisualTreeAsset videoTemplateVisualTreeAsset,
            VisualElement containerVisualElement,
            string text) {
            // Break down complex text and add all components

            // ##REF##video_small, KGFAnwkO0Pk, What are Value Types and Reference Types in C#? (Class vs Struct)##REF##
            // ##REF##code, Console.WriteLine("Qwerty");##REF##

            // Parse HTML
            text = text.Replace("<h1>", "<size=20>");
            text = text.Replace("</h1>", "</size>");
            text = text.Replace("<strong>", "<b>");
            text = text.Replace("</strong>", "</b>");
            text = text.Replace("<p>", "<br>");
            text = text.Replace("</p>", "");

            string refTag = "##REF##";
            string textRemaining = text;
            int safety = 0;
            while (textRemaining.IndexOf(refTag) != -1 && safety < 100) {
                // Found Ref Tag
                int refTagIndex = textRemaining.IndexOf(refTag);

                // Add before text
                string textBefore = textRemaining.Substring(0, refTagIndex);
                AddText(textTemplateVisualTreeAsset, containerVisualElement, textBefore);

                string refData = textRemaining.Substring(refTagIndex + refTag.Length);
                refData = refData.Substring(0, refData.IndexOf(refTag));

                textRemaining = textRemaining.Substring(refTagIndex + refTag.Length);
                textRemaining = textRemaining.Substring(textRemaining.IndexOf(refTag) + refTag.Length);

                string[] refDataArray = refData.Split(',');
                string refType = refDataArray[0].Trim();
                switch (refType) {
                    case "video_small":
                        string youTubeId = refDataArray[1].Trim();
                        string youTubeTitle = refDataArray[2].Trim();
                        string thumbnailUrl = $"https://img.youtube.com/vi/{youTubeId}/mqdefault.jpg";
                        AddVideoReference(videoTemplateVisualTreeAsset, containerVisualElement, thumbnailUrl, youTubeTitle, "https://www.youtube.com/watch?v=" + youTubeId);
                        break;
                    case "code":
                        AddCode(codeTemplateVisualTreeAsset, containerVisualElement, refData.Substring(refType.Length + 1).Trim());
                        break;
                }
                safety++;
            }
            // No more Ref tags found
            AddText(textTemplateVisualTreeAsset, containerVisualElement, textRemaining);
        }

        public static void AddText(VisualTreeAsset textTemplateVisualTreeAsset, VisualElement containerVisualElement, string text) {
            VisualElement textVisualElement = textTemplateVisualTreeAsset.Instantiate();

            Label textLabel = textVisualElement.Q<Label>("textLabel");
            textLabel.text = text;

            containerVisualElement.Add(textVisualElement);
        }

        public static void AddCode(VisualTreeAsset codeTemplateVisualTreeAsset, VisualElement containerVisualElement, string codeString) {
            VisualElement codeVisualElement = codeTemplateVisualTreeAsset.Instantiate();

            Label textLabel = codeVisualElement.Q<Label>("codeLabel");
            textLabel.text = codeString;

            containerVisualElement.Add(codeVisualElement);
        }

        public static void AddVideoReference(VisualTreeAsset videoTemplateVisualTreeAsset, VisualElement containerVisualElement, string imageUrl, string title, string url, VideoReferenceSettings videoReferenceSettings = null) {
            Sprite waitingSprite = null;
            VisualElement videoVisualElement = AddVideoReference(videoTemplateVisualTreeAsset, containerVisualElement, waitingSprite, title, url, videoReferenceSettings);

            UnityWebRequest unityWebRequest = UnityWebRequestTexture.GetTexture(imageUrl);
            unityWebRequest.SendWebRequest().completed += (AsyncOperation asyncOperation) => {
                try {
                    UnityWebRequestAsyncOperation unityWebRequestAsyncOperation = asyncOperation as UnityWebRequestAsyncOperation;

                    if (unityWebRequestAsyncOperation.webRequest.result == UnityWebRequest.Result.ConnectionError ||
                        unityWebRequestAsyncOperation.webRequest.result == UnityWebRequest.Result.DataProcessingError ||
                        unityWebRequestAsyncOperation.webRequest.result == UnityWebRequest.Result.ProtocolError) {
                        // Error
                        //onError(unityWebRequest.error);
                    } else {
                        DownloadHandlerTexture downloadHandlerTexture = unityWebRequest.downloadHandler as DownloadHandlerTexture;
                        VisualElement imageVisualElement = videoVisualElement.Q<VisualElement>("image");
                        imageVisualElement.style.backgroundImage = new StyleBackground(downloadHandlerTexture.texture);
                    }
                } catch (Exception) {
                }
                unityWebRequest.Dispose();
            };
        }

        private static void SetBackgroundImage(VisualElement visualElement, string imageUrl) {
            UnityWebRequest unityWebRequest = UnityWebRequestTexture.GetTexture(imageUrl);
            unityWebRequest.SendWebRequest().completed += (AsyncOperation asyncOperation) => {
                try {
                    UnityWebRequestAsyncOperation unityWebRequestAsyncOperation = asyncOperation as UnityWebRequestAsyncOperation;

                    if (unityWebRequestAsyncOperation.webRequest.result == UnityWebRequest.Result.ConnectionError ||
                        unityWebRequestAsyncOperation.webRequest.result == UnityWebRequest.Result.DataProcessingError ||
                        unityWebRequestAsyncOperation.webRequest.result == UnityWebRequest.Result.ProtocolError) {
                        // Error
                        //Debug.Log("Error Contacting URL: " + unityWebRequest.error);
                        //DownloadHandlerTexture downloadHandlerTexture = unityWebRequest.downloadHandler as DownloadHandlerTexture;
                        //Debug.Log(downloadHandlerTexture.error);
                        //onError(unityWebRequest.error);
                    } else {
                        DownloadHandlerTexture downloadHandlerTexture = unityWebRequest.downloadHandler as DownloadHandlerTexture;
                        visualElement.style.backgroundImage = new StyleBackground(downloadHandlerTexture.texture);
                    }
                } catch (Exception) {
                }
                unityWebRequest.Dispose();
            };
        }

        public static VisualElement AddVideoReference(VisualTreeAsset videoTemplateVisualTreeAsset, VisualElement containerVisualElement, Sprite sprite, string title, string url, VideoReferenceSettings videoReferenceSettings = null) {
            VisualElement videoVisualElement = videoTemplateVisualTreeAsset.Instantiate();

            VisualElement videoContainer = videoVisualElement.Q<VisualElement>("videoContainer");
            videoContainer.RegisterCallback<ClickEvent>((ClickEvent clickEvent) => {
                Debug.Log("Clicked: " + url);
                Application.OpenURL(url);
            });

            VisualElement imageVisualElement = videoContainer.Q<VisualElement>("image");
            imageVisualElement.style.backgroundImage = new StyleBackground(sprite);

            Label textLabel = videoContainer.Q<Label>("titleLabel");
            textLabel.text = title;

            if (videoReferenceSettings != null) {
                if (videoReferenceSettings.height != null) {
                    imageVisualElement.style.height = new StyleLength(videoReferenceSettings.height.Value);
                }
                if (videoReferenceSettings.fontSize != null) {
                    textLabel.style.fontSize = new StyleLength(videoReferenceSettings.fontSize.Value);
                }
            }

            containerVisualElement.Add(videoVisualElement);

            return videoVisualElement;
        }

        public class VideoReferenceSettings {
            public float? height;
            public float? fontSize;
        }

        private SubWindow GetActiveSubWindow() {
            if (toolListVisualElement.style.display == DisplayStyle.Flex) {
                return SubWindow.ToolList;
            }
            if (toolSingleVisualElement.style.display == DisplayStyle.Flex) {
                return SubWindow.ToolSingle;
            }
            return SubWindow.MainMenu;
        }

        public void CreateGUI() {
            // Each editor window contains a root VisualElement object
            VisualElement root = rootVisualElement;

            // Instantiate UXML
            VisualElement rootVisualTreeAsset = visualTreeAsset.Instantiate();
            rootVisualTreeAsset.style.flexGrow = 1f;
            root.Add(rootVisualTreeAsset);

            mainMenuVisualElement = root.Q<VisualElement>("mainMenu");
            toolListVisualElement = root.Q<VisualElement>("toolList");
            toolSingleVisualElement = root.Q<VisualElement>("toolSingle");

            root.Q<Label>("versionLabel").text = CodeMonkeyToolkitSO.GetCodeMonkeyToolkitSO().currentVersion;

            Button toolListButton = mainMenuVisualElement.Q<Button>("toolListButton");
            toolListButton.RegisterCallback((ClickEvent clickEvent) => {
                ShowToolList();
            });

            CreateToolList(null);

            Button toolListBackToMainMenuButton = toolListVisualElement.Q<Button>("backToMainMenuButton");
            toolListBackToMainMenuButton.RegisterCallback((ClickEvent clickEvent) => {
                ShowMainMenu();
            });

            TextField searchTextField = toolListVisualElement.Q<TextField>("searchTextField");
            searchTextField.RegisterCallback((ChangeEvent<string> changeEvent) => {
                CreateToolList(changeEvent.newValue);
            });

            // Filter Preset Buttons
            toolListVisualElement.Q<Button>("utilityButton").RegisterCallback((ClickEvent clickEvent) => {
                searchTextField.value = "Utility";
            });
            toolListVisualElement.Q<Button>("uiButton").RegisterCallback((ClickEvent clickEvent) => {
                searchTextField.value = "UI";
            });
            toolListVisualElement.Q<Button>("systemButton").RegisterCallback((ClickEvent clickEvent) => {
                searchTextField.value = "System";
            });
            toolListVisualElement.Q<Button>("mechanicButton").RegisterCallback((ClickEvent clickEvent) => {
                searchTextField.value = "Mechanic";
            });
            toolListVisualElement.Q<Button>("controllerButton").RegisterCallback((ClickEvent clickEvent) => {
                searchTextField.value = "Controller";
            });
            toolListVisualElement.Q<Button>("polishButton").RegisterCallback((ClickEvent clickEvent) => {
                searchTextField.value = "Polish";
            });
            toolListVisualElement.Q<Button>("gridButton").RegisterCallback((ClickEvent clickEvent) => {
                searchTextField.value = "Grid";
            });
            toolListVisualElement.Q<Button>("shaderButton").RegisterCallback((ClickEvent clickEvent) => {
                searchTextField.value = "Shader";
            });

            Button backToToolListButton = toolSingleVisualElement.Q<Button>("backToToolListButton");
            backToToolListButton.RegisterCallback((ClickEvent clickEvent) => {
                ShowToolList();
            });

            // ToolSingle menu
            Button openDemoButton = toolSingleVisualElement.Q<Button>("openDemoButton");
            openDemoButton.RegisterCallback((ClickEvent clickEvent) => {
                if (toolSO == null) return;
                EditorSceneManager.OpenScene(AssetDatabase.GetAssetPath(toolSO.demoScene));
                EditorGUIUtility.PingObject(toolSO.demoScene);
            });
            Button pingButton = toolSingleVisualElement.Q<Button>("pingButton");
            pingButton.RegisterCallback((ClickEvent clickEvent) => {
                if (toolSO == null) return;
                EditorGUIUtility.PingObject(toolSO.demoScene);
            });

            Button walkthroughVideoButton = toolSingleVisualElement.Q<Button>("walkthroughVideoButton");
            walkthroughVideoButton.RegisterCallback((ClickEvent clickEvent) => {
                if (toolSO == null) return;
                string walkthroughVideoUrl = $"https://www.youtube.com/watch?v={toolSO.walkthroughVideoYouTubeVideo.youTubeId}";
                Application.OpenURL(walkthroughVideoUrl);
            });

            Button tutorialVideoButton = toolSingleVisualElement.Q<Button>("tutorialVideoButton");
            tutorialVideoButton.RegisterCallback((ClickEvent clickEvent) => {
                if (toolSO == null) return;
                string tutorialVideoUrl = $"https://unitycodemonkey.com/video.php?v={toolSO.tutorialVideoYouTubeVideo.youTubeId}";
                Application.OpenURL(tutorialVideoUrl);
            });


            switch (lastSubWindow) {
                case SubWindow.MainMenu:
                    ShowMainMenu();
                    break;
                case SubWindow.ToolList:
                    ShowToolList();
                    break;
                case SubWindow.ToolSingle:
                    ShowTool(toolSO);
                    break;
            }
        }

        private void CreateToolList(string filter) {
            List<ToolSO> toolSOList;
            if (string.IsNullOrEmpty(filter)) {
                toolSOList = codeMonkeyToolkitSO.toolSOList;
            } else {
                toolSOList = codeMonkeyToolkitSO.GetFilteredToolSOList(filter);
            }

            // Setup Tool List
            ScrollView toolListScrollView = toolListVisualElement.Q<ScrollView>();

            DestroyChildren(toolListScrollView);

            foreach (ToolSO toolSO in toolSOList) {
                VisualElement toolListEntryVisualElement = toolListEntryVisualTreeAsset.Instantiate();

                Label titleLabel = toolListEntryVisualElement.Q<Label>("titleLabel");
                titleLabel.text = toolSO.nameString;

                Label descriptionLabel = toolListEntryVisualElement.Q<Label>("descriptionLabel");
                descriptionLabel.text = toolSO.description;

                VisualElement iconVisualElement = toolListEntryVisualElement.Q<VisualElement>("icon");
                iconVisualElement.style.backgroundImage = new StyleBackground(toolSO.iconSprite);

                ToolSO thisToolSO = toolSO;
                toolListEntryVisualElement.RegisterCallback((ClickEvent clickEvent) => {
                    lastListScrollPosition = toolListScrollView.scrollOffset;
                    ShowTool(thisToolSO);
                });

                VisualElement tagsContainerVisualElement = toolListEntryVisualElement.Q<VisualElement>("tagsContainer");
                tagsContainerVisualElement.Clear();

                string[] tagArray = toolSO.GetTagArray();

                foreach (string tag in tagArray) {
                    VisualElement toolTagSingleVisualElement = toolTagSingleVisualTreeAsset.Instantiate();

                    Label textLabel = toolTagSingleVisualElement.Q<Label>("textLabel");
                    textLabel.text = tag;

                    tagsContainerVisualElement.Add(toolTagSingleVisualElement);
                }

                toolListScrollView.Add(toolListEntryVisualElement);
            }
        }

        private void ShowToolList() {
            toolListVisualElement.style.display = DisplayStyle.Flex;
            toolSingleVisualElement.style.display = DisplayStyle.None;
            mainMenuVisualElement.style.display = DisplayStyle.None;

            ScrollView toolListScrollView = toolListVisualElement.Q<ScrollView>();
            toolListScrollView.scrollOffset = lastListScrollPosition;
            toolListScrollView.schedule.Execute(() => {
                toolListScrollView.scrollOffset = lastListScrollPosition;
            });

            lastSubWindow = SubWindow.ToolList;
        }

        private void ShowTool(ToolSO toolSO) {
            this.toolSO = toolSO;

            lastSubWindow = SubWindow.ToolSingle;

            toolListVisualElement.style.display = DisplayStyle.None;
            toolSingleVisualElement.style.display = DisplayStyle.Flex;
            mainMenuVisualElement.style.display = DisplayStyle.None;

            Label titleLabel = toolSingleVisualElement.Q<Label>("titleLabel");
            Label descriptionLabel = toolSingleVisualElement.Q<Label>("descriptionLabel");

            titleLabel.text = toolSO.nameString;
            descriptionLabel.text = toolSO.description;

            VisualElement iconVisualElement = toolSingleVisualElement.Q<VisualElement>("icon");
            iconVisualElement.style.backgroundImage = new StyleBackground(toolSO.iconSprite);


            VisualElement tutorialVideoContainerVisualElement = toolSingleVisualElement.Q<VisualElement>("tutorialVideoContainer");
            tutorialVideoContainerVisualElement.Clear();

            if (toolSO.tutorialVideoYouTubeVideo.youTubeId != "") {
                string thumbnailUrl = $"https://img.youtube.com/vi/{toolSO.tutorialVideoYouTubeVideo.youTubeId}/mqdefault.jpg";
                string tutorialVideoUrl = $"https://unitycodemonkey.com/video.php?v={toolSO.tutorialVideoYouTubeVideo.youTubeId}";
                AddVideoReference(
                    videoTemplateVisualTreeAsset,
                    tutorialVideoContainerVisualElement,
                    thumbnailUrl,
                    toolSO.tutorialVideoYouTubeVideo.title,
                    tutorialVideoUrl,
                    new VideoReferenceSettings {
                        height = 150,
                        fontSize = 12,
                    }
                );
            }

            Button tutorialVideoButton = toolSingleVisualElement.Q<Button>("tutorialVideoButton");
            Label noteLabel = toolSingleVisualElement.Q<Label>("noteLabel");
            if (toolSO.tutorialVideoYouTubeVideo.youTubeId == "") {
                tutorialVideoButton.style.display = DisplayStyle.None;
                noteLabel.style.display = DisplayStyle.None;
            } else {
                tutorialVideoButton.style.display = DisplayStyle.Flex;
                noteLabel.style.display = DisplayStyle.Flex;
            }

            // Show Related
            VisualElement relatedVideosVisualElement = toolSingleVisualElement.Q<VisualElement>("relatedVideos");

            if (toolSO.relatedVideoYouTubeVideoArray != null && toolSO.relatedVideoYouTubeVideoArray.Length > 0) {
                // Has related videos
                relatedVideosVisualElement.style.display = DisplayStyle.Flex;
                VisualElement relatedVideosContainerVisualElement = toolSingleVisualElement.Q<VisualElement>("relatedVideosContainer");

                relatedVideosContainerVisualElement.Clear();

                foreach (YouTubeVideo youTubeVideo in toolSO.relatedVideoYouTubeVideoArray) {
                    AddRelatedVideo(youTubeVideo, relatedVideosContainerVisualElement);

                    void AddRelatedVideo(YouTubeVideo youTubeVideo, VisualElement containerVisualElement) {
                        string thumbnailUrl = $"https://img.youtube.com/vi/{youTubeVideo.youTubeId}/mqdefault.jpg";
                        string url = $"https://unitycodemonkey.com/video.php?v={youTubeVideo.youTubeId}";
                        AddVideoReference(
                            videoTemplateVisualTreeAsset,
                            containerVisualElement,
                            thumbnailUrl,
                            youTubeVideo.title,
                            url,
                            new VideoReferenceSettings {
                                height = 80,
                                fontSize = 9,
                            }
                        );
                    }
                }
            } else {
                // Does not have related videos
                relatedVideosVisualElement.style.display = DisplayStyle.None;
            }
        }

        private void ShowMainMenu() {
            toolListVisualElement.style.display = DisplayStyle.None;
            toolSingleVisualElement.style.display = DisplayStyle.None;
            mainMenuVisualElement.style.display = DisplayStyle.Flex;

            lastSubWindow = SubWindow.MainMenu;

            // Check for updates
            CodeMonkeyToolkitSO.CheckForUpdates((CodeMonkeyToolkitSO.LastUpdateResponse lastUpdateResponse) => {
                if (!lastUpdateResponse.enabled || codeMonkeyToolkitSO.currentVersion == lastUpdateResponse.version) {
                    mainMenuVisualElement.Q<VisualElement>("checkingForUpdates").style.display = DisplayStyle.None;
                    return;
                }

                VisualElement checkingForUpdatesVisualElement =
                    mainMenuVisualElement.Q<VisualElement>("checkingForUpdates");
                checkingForUpdatesVisualElement.style.display = DisplayStyle.Flex;
                Label textLabel = checkingForUpdatesVisualElement.Q<Label>();
                textLabel.text = "New version available!\n" +
                    codeMonkeyToolkitSO.currentVersion + " -> " + lastUpdateResponse.version + "\n" +
                    "<u>Click here!</u>";

                textLabel.RegisterCallback((ClickEvent clickEvent) => {
                    Application.OpenURL(lastUpdateResponse.versionUrl);
                });
            });

            // Message
            VisualElement messageVisualElement =
                mainMenuVisualElement.Q<VisualElement>("message");

            CodeMonkeyToolkitSO.GetLatestMessage((CodeMonkeyToolkitSO.WebsiteLatestMessage websiteLatestMessage) => {
                messageVisualElement.Q<Label>("messageLabel").text = websiteLatestMessage.text;
            });


            // QOTD
            VisualElement qotdVisualElement =
                mainMenuVisualElement.Q<VisualElement>("qotd");

            Action openQotdURL = () => {
                string qotdUrl = "https://unitycodemonkey.com/qotd_ask.php?q=30";
                Application.OpenURL(qotdUrl);
            };
            qotdVisualElement.RegisterCallback((ClickEvent clickEvent) => {
                openQotdURL();
            });

            qotdVisualElement.Q<Label>("questionLabel").text = "...";
            qotdVisualElement.Q<Button>("answerAButton").style.display = DisplayStyle.None;
            qotdVisualElement.Q<Button>("answerBButton").style.display = DisplayStyle.None;
            qotdVisualElement.Q<Button>("answerCButton").style.display = DisplayStyle.None;
            qotdVisualElement.Q<Button>("answerDButton").style.display = DisplayStyle.None;
            qotdVisualElement.Q<Button>("answerEButton").style.display = DisplayStyle.None;

            CodeMonkeyToolkitSO.GetLastQOTD((CodeMonkeyToolkitSO.LastQOTDResponse lastQOTDResponse) => {
                openQotdURL = () => {
                    string qotdUrl = "https://unitycodemonkey.com/qotd_ask.php?q=" + lastQOTDResponse.questionId;
                    Application.OpenURL(qotdUrl);
                };

                qotdVisualElement.Q<Label>("questionLabel").text = lastQOTDResponse.questionText;
                if (!string.IsNullOrEmpty(lastQOTDResponse.answerA)) {
                    qotdVisualElement.Q<Button>("answerAButton").style.display = DisplayStyle.Flex;
                    qotdVisualElement.Q<Button>("answerAButton").text = lastQOTDResponse.answerA;
                }
                if (!string.IsNullOrEmpty(lastQOTDResponse.answerB)) {
                    qotdVisualElement.Q<Button>("answerBButton").style.display = DisplayStyle.Flex;
                    qotdVisualElement.Q<Button>("answerBButton").text = lastQOTDResponse.answerB;
                }
                if (!string.IsNullOrEmpty(lastQOTDResponse.answerC)) {
                    qotdVisualElement.Q<Button>("answerCButton").style.display = DisplayStyle.Flex;
                    qotdVisualElement.Q<Button>("answerCButton").text = lastQOTDResponse.answerC;
                }
                if (!string.IsNullOrEmpty(lastQOTDResponse.answerD)) {
                    qotdVisualElement.Q<Button>("answerDButton").style.display = DisplayStyle.Flex;
                    qotdVisualElement.Q<Button>("answerDButton").text = lastQOTDResponse.answerD;
                }
                if (!string.IsNullOrEmpty(lastQOTDResponse.answerE)) {
                    qotdVisualElement.Q<Button>("answerEButton").style.display = DisplayStyle.Flex;
                    qotdVisualElement.Q<Button>("answerEButton").text = lastQOTDResponse.answerE;
                }
            });


            // Dynamic Message
            VisualElement dynamicMessageVisualElement =
                mainMenuVisualElement.Q<VisualElement>("dynamicMessage");

            Func<string> getDynamicMessageURL = () => "https://unitycodemonkey.com/";
            dynamicMessageVisualElement.RegisterCallback((ClickEvent clickEvent) => {
                Application.OpenURL(getDynamicMessageURL());
            });


            // Latest Videos
            VisualElement latestVideosVisualElement =
                mainMenuVisualElement.Q<VisualElement>("latestVideos");

            latestVideosVisualElement.Q<VisualElement>("_1Container").Clear();
            latestVideosVisualElement.Q<VisualElement>("_2Container").Clear();
            latestVideosVisualElement.Q<VisualElement>("_3Container").Clear();
            latestVideosVisualElement.Q<VisualElement>("_4Container").Clear();



            CodeMonkeyToolkitSO.GetWebsiteLatestVideos((CodeMonkeyToolkitSO.LatestVideos latestVideos) => {
                AddLatestVideoReference(latestVideos.videos[0], latestVideosVisualElement.Q<VisualElement>("_1Container"));
                AddLatestVideoReference(latestVideos.videos[1], latestVideosVisualElement.Q<VisualElement>("_2Container"));
                AddLatestVideoReference(latestVideos.videos[2], latestVideosVisualElement.Q<VisualElement>("_3Container"));
                AddLatestVideoReference(latestVideos.videos[3], latestVideosVisualElement.Q<VisualElement>("_4Container"));
            });

            void AddLatestVideoReference(CodeMonkeyToolkitSO.LatestVideoSingle latestVideoSingle, VisualElement containerVisualElement) {
                string thumbnailUrl = $"https://img.youtube.com/vi/{latestVideoSingle.youTubeId}/mqdefault.jpg";
                string url = $"https://unitycodemonkey.com/video.php?v={latestVideoSingle.youTubeId}";
                AddVideoReference(
                    videoTemplateVisualTreeAsset,
                    containerVisualElement,
                    thumbnailUrl,
                    latestVideoSingle.title,
                    url,
                    new VideoReferenceSettings {
                        height = 80,
                        fontSize = 9,
                    }
                );
            }


            // DynamicHeader
            VisualElement dynamicHeaderVisualElement =
                mainMenuVisualElement.Q<VisualElement>("dynamicHeader");

            dynamicHeaderVisualElement.Q<Label>("text").text = "...";
            dynamicHeaderVisualElement.Q<VisualElement>("image").style.display = DisplayStyle.None;

            Func<string> getTopLinkUrl = () => "https://unitycodemonkey.com/";
            dynamicHeaderVisualElement.Q<VisualElement>("image").RegisterCallback((ClickEvent clickEvent) => {
                Application.OpenURL(getTopLinkUrl());
            });

            CodeMonkeyToolkitSO.GetLastDynamicHeader((CodeMonkeyToolkitSO.LastDynamicHeaderResponse lastDynamicHeaderResponse) => {
                getTopLinkUrl = () => "https://cmonkey.co/" + lastDynamicHeaderResponse.topLink;

                dynamicHeaderVisualElement.Q<VisualElement>("image").style.display = DisplayStyle.Flex;
                if (lastDynamicHeaderResponse.topImageUrl.Substring(lastDynamicHeaderResponse.topImageUrl.Length - 4) != ".gif") {
                    // Not a gif
                    SetBackgroundImage(dynamicHeaderVisualElement.Q<VisualElement>("image"), lastDynamicHeaderResponse.topImageUrl);
                }

                dynamicHeaderVisualElement.Q<Label>("text").text =
                    "<a href='https://cmonkey.co/" + lastDynamicHeaderResponse.topLink + "'><u>" + lastDynamicHeaderResponse.topText + "</u></a>\n\n" +
                    "<a href='https://cmonkey.co/" + lastDynamicHeaderResponse.bottomLink + "'><u>" + lastDynamicHeaderResponse.bottomText + "</u></a>";
            });
        }


    }





}